package com.kingyea.mobilepolice.organization.service.impl;

import com.google.common.collect.Lists;
import com.kingyea.mobilepolice.dictionary.bean.Dictionary;
import com.kingyea.mobilepolice.dictionary.dao.DictionaryMapper;
import com.kingyea.mobilepolice.organization.bean.Organization;
import com.kingyea.mobilepolice.organization.bean.OrganizationCondition;
import com.kingyea.mobilepolice.organization.bean.OrganizationVo;
import com.kingyea.mobilepolice.organization.dao.OrganizationMapper;
import com.kingyea.mobilepolice.organization.service.OrganizationService;
import com.kingyea.mobilepolice.security.SecurityUtils;
import com.kingyea.mobilepolice.system.Result;
import com.kingyea.mobilepolice.system.StateCode;
import com.kingyea.mobilepolice.user.bean.User;
import com.kingyea.mobilepolice.user.dao.UserMapper;
import com.kingyea.mobilepolice.userorg.bean.UserOrg;
import com.kingyea.mobilepolice.userorg.bean.UserOrgCondition;
import com.kingyea.mobilepolice.userorg.dao.UserOrgMapper;
import com.kingyea.mobilepolice.util.Constants;
import com.kingyea.mobilepolice.util.ExceptionConditions;
import com.kingyea.mobilepolice.util.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Mr.Lin
 * @version v1.0.0
 * @description Organization 实现类
 * @date Created in 2018-03-30 15:26:51
 */
@Service
@Transactional
public class OrganizationServiceImpl implements OrganizationService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OrganizationServiceImpl.class);

    @Resource
    private OrganizationMapper organizationMapper;

    @Resource
    private UserOrgMapper userOrgMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    DictionaryMapper dictionaryMapper;

    /**
     * 通过ID查找对象
     *
     * @param orgId
     * @return
     */
    @Override
    public Organization getById(Integer orgId) {
        return this.organizationMapper.getById(orgId);
    }

    /**
     * 通过SERIALNO查找对象
     *
     * @param serialNo
     * @return
     */
    @Override
    public Organization getBySerialNo(String serialNo) {
        return this.organizationMapper.getBySerialNo(serialNo);
    }

    /**
     * 列表
     *
     * @param
     * @return
     */
    @Override
    public List<Organization> search(OrganizationCondition condition) throws Exception {
        List<Organization> list = organizationMapper.search(condition);
        return list;
    }

    /**
     * 通过条件获取数据
     *
     * @param condition
     * @return
     * @throws Exception
     */
    @Override
    public List<Organization> queryByCondition(OrganizationCondition condition) throws Exception {
        return organizationMapper.queryByCondition(condition);
    }

    /**
     * 删除
     *
     * @param orgId
     * @return
     */
    @Override
    public int deleteById(Integer orgId) {
        Organization org = organizationMapper.getById(orgId);
        userOrgMapper.deleteByOrgSerialNo(org.getOrgSerialNo());
        return organizationMapper.deleteById(orgId);
    }

    /**
     * 添加部门，名称可以重复
     *
     * @param organization
     * @return
     */
    @Override
    @Transactional
    public Organization save(Organization organization) {
        ExceptionConditions.checkNotNull(organization, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(organization.getType(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getIcode(), StateCode.NO_ARGUMENT_ERROR);
//		ExceptionConditions.checkStringNotEmpty(organization.getCode(), StateCode.NO_ARGUMENT_ERROR);

        if (StringUtils.isEmpty(organization.getParentSerialNo())) {
            organization.setParentSerialNo(Constants.TOP_LEVEL_ORGANIZATION);
        } else {
            ExceptionConditions.checkNotNull(organizationMapper.getBySerialNo(organization.getParentSerialNo()), StateCode.SERVER_DATA_MISSING_ERROR);
        }
        organization.setOrgSerialNo(RandomUtils.genUUID());
        organization.setStatus(Constants.ORGANIZATION_STATUS_WEISHENHE);
        organization.setCreatedBy(SecurityUtils.getCurrentUser().getUserId());
        organization.setLastUpdatedBy(SecurityUtils.getCurrentUser().getUserId());
        organization.setCreatedDate(new Date());
        organization.setLastUpdatedDate(new Date());

        //给创建人依赖这部门
        UserOrg orgOfUser = new UserOrg();
        orgOfUser.setUserSerialNo(SecurityUtils.getCurrentUser().getUserId());
        orgOfUser.setOrgSerialNo(organization.getOrgSerialNo());
        orgOfUser.setParentNo(organization.getParentSerialNo());
        userOrgMapper.addAOfUser(orgOfUser);

        ExceptionConditions.checkArgument(organizationMapper.save(organization) > 0, StateCode.SYSTEM_ERROR);
        return organization;
    }

    /**
     * 更新
     *
     * @param organization
     * @return
     */
    @Override
    public Organization update(Organization organization) throws Exception {
        ExceptionConditions.checkNotNull(organization, StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getOrgSerialNo(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkNotNull(organization.getType(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getName(), StateCode.NO_ARGUMENT_ERROR);
        ExceptionConditions.checkStringNotEmpty(organization.getIcode(), StateCode.NO_ARGUMENT_ERROR);
//		ExceptionConditions.checkStringNotEmpty(organization.getCode(), StateCode.NO_ARGUMENT_ERROR);
        //暂时做不到，除非在创建时把部门依赖给管理员，目前只要有权限就可以删除任意部门
//		ExceptionConditions.checkArgument(userOrgMapper.findByUserIdAndOrgSerialNo(SecurityUtils.getCurrentUser().getUserId(), organization.getOrgSerialNo()).size() > 0, StateCode.NO_PERMISSION_ACCESSS_ERROR);
        Organization oldOrg = organizationMapper.getBySerialNo(organization.getOrgSerialNo());
        ExceptionConditions.checkNotNull(oldOrg, StateCode.SERVER_DATA_MISSING_ERROR);

        if (null == organization.getParentSerialNo()) {
            organization.setParentSerialNo(Constants.TOP_LEVEL_ORGANIZATION);
        }
        organization.setLastUpdatedDate(new Date());
        organization.setLastUpdatedBy(SecurityUtils.getCurrentUser().getUserId());
        ExceptionConditions.checkArgument(organizationMapper.update(organization) > 0, StateCode.SYSTEM_ERROR);
        return organization;
    }

    /**
     * @Description: 地市一级 只查询一级和二级部门
     * @param: [condition]
     * @return: java.util.List<com.kingyea.mobilepolice.organization.bean.OrganizationVo>
     * @author: cxc
     * @Date: 2018/5/29
     */
    @Override
    public List<OrganizationVo> searchPctree(OrganizationCondition condition) {
        List<OrganizationVo> topOrganizationList = Lists.newArrayList();
        condition.setPageAble(false);
        condition.setParentSerialNo(Constants.TOP_LEVEL_ORGANIZATION);
        List<Organization> list = organizationMapper.search(condition);
        List<String> topParentSerialNoList = list.stream().map(Organization::getOrgSerialNo).distinct().collect(Collectors.toList());
        condition.setParentSerialNo(null);
        condition.setParentSerialNos(topParentSerialNoList);
        List<Organization> towOrgList = organizationMapper.search(condition);

        list.addAll(towOrgList);
        List<OrganizationVo> voList = list.stream().map(bean -> {
            OrganizationVo vo = new OrganizationVo();
            BeanUtils.copyProperties(bean, vo);
            if (Constants.TOP_LEVEL_ORGANIZATION.equals(bean.getParentSerialNo())) {
                topOrganizationList.add(vo);
            }
            return vo;
        }).collect(Collectors.toList());

        treeOp(voList);
        return topOrganizationList;
    }



    /**
     * 树结构--用于显示所有的部门树
     *
     * @param
     * @return
     */
    @Override
    public List<OrganizationVo> searchTree(OrganizationCondition condition) {
        List<OrganizationVo> topOrganizationList = Lists.newArrayList();
        condition.setPageAble(false);

        List<Organization> list = organizationMapper.search(condition);

        List<OrganizationVo> voList = list.stream().map(bean -> {
            OrganizationVo vo = new OrganizationVo();
            BeanUtils.copyProperties(bean, vo);
            if (Constants.TOP_LEVEL_ORGANIZATION.equals(bean.getParentSerialNo())) {
                topOrganizationList.add(vo);
            }
            return vo;
        }).collect(Collectors.toList());

        treeOp(voList);
        return topOrganizationList;
    }

    /**
     * @Description: 用户管理的部门 清空数据
     * @Param: [userSerialNo]
     * @return: java.lang.Boolean
     * @Author: cxc
     * @Date: 2018.04.09 16:15
     */
    @Override
    public Boolean delAllOrgByUserSerialNo(String userSerialNo) {
        userOrgMapper.deletAllOfUser(userSerialNo);
        return Boolean.TRUE;
    }



    /**
     * @Description: 用户管理的部门 重新构建
     * @Param: [userOrgList]
     * @return: java.lang.Boolean
     * @Author: cxc
     * @Date: 2018.04.09 16:15
     */
    @Transactional
    @Override
    public Boolean addAllOrgOfUser(String userId, List<UserOrg> userOrgList) {
        userOrgMapper.deletAllOfUser(userId);
        List<UserOrg> list = userOrgList.stream().map(u -> {
            if (!userOrgList.stream().filter(o -> u.getParentNo().equals(o.getOrgSerialNo())).findFirst().isPresent()) {
                u.setParentNo(Constants.TOP_LEVEL_ORGANIZATION);
            }
            u.setUserSerialNo(userId);
            return u;
        }).collect(Collectors.toList());
        return Integer.valueOf(userOrgList.size()).equals(userOrgMapper.batchSave(list));
    }

    @Override
    public List<OrganizationVo> searchAllOrgOfUser(String userSerialNo) {
        List<UserOrg> userOrgList = userOrgMapper.searchAllOfUser(userSerialNo);
        if (userOrgList.size() > 0) {

            List<String> topOrgIdList = Lists.newArrayList();
            Set<String> orgSerialNoSet = userOrgList.stream().map(uo -> {
                if (Constants.TOP_LEVEL_ORGANIZATION.equals(uo.getParentNo())) {
                    topOrgIdList.add(uo.getOrgSerialNo());
                }
                return uo.getOrgSerialNo();
            }).collect(Collectors.toSet());

            OrganizationCondition condition = new OrganizationCondition();
            condition.setOrgIds(new ArrayList<>(orgSerialNoSet));
            condition.setPageSize(orgSerialNoSet.size());
            List<Organization> organizationList = organizationMapper.search(condition);

            List<OrganizationVo> topOrganizationList = Lists.newArrayList();
            List<OrganizationVo> voList = organizationList.stream().map(bean -> {
                OrganizationVo vo = new OrganizationVo();
                BeanUtils.copyProperties(bean, vo);
                if (topOrgIdList.contains(bean.getOrgSerialNo())) {
                    topOrganizationList.add(vo);
                }
                return vo;
            }).collect(Collectors.toList());
            treeOp(voList);//
            return topOrganizationList;
        }
        return Lists.newArrayList();
    }


    @Override
    public List<Organization> search(UserOrgCondition userOrgCondition) {
        List<UserOrg> userOrgList = userOrgMapper.search(userOrgCondition);
        if (userOrgList.size() > 0) {

            List<String> topOrgIdList = Lists.newArrayList();
            Set<String> orgSerialNoSet = userOrgList.stream().map(uo -> {
                if (Constants.TOP_LEVEL_ORGANIZATION.equals(uo.getParentNo())) {
                    topOrgIdList.add(uo.getOrgSerialNo());
                }
                return uo.getOrgSerialNo();
            }).collect(Collectors.toSet());

            OrganizationCondition condition = new OrganizationCondition();
            condition.setOrgIds(new ArrayList<>(orgSerialNoSet));
            condition.setPageSize(orgSerialNoSet.size());
            List<Organization> organizationList = organizationMapper.search(condition);

			/*List<OrganizationVo> topOrganizationList = Lists.newArrayList();
			List<OrganizationVo> voList = organizationList.stream().map(bean -> {
				OrganizationVo vo = new OrganizationVo();
				BeanUtils.copyProperties(bean, vo);
				if(topOrgIdList.contains(bean.getOrgSerialNo())){
					topOrganizationList.add(vo);
				}
				return vo;
			}).collect(Collectors.toList());
			treeOp(voList);//*/
            return organizationList;
        }
        return Lists.newArrayList();
    }

    /**
     * @Description: 封装成树结构数据
     * @Param: [voList]
     * @return: void
     * @Author: cxc
     * @Date: 2018.04.09 11:15
     */
    private void treeOp(List<OrganizationVo> voList) {
        voList.stream().forEach(vo1 -> {
            List<OrganizationVo> childrenList = voList.stream().filter(vo2 -> vo1.getOrgSerialNo().equals(vo2.getParentSerialNo())).collect(Collectors.toList());
            vo1.setOrganizationVos(childrenList);
        });
    }

    /**
     * @Description: 用户是否存在权限控制部门
     * @Param: [userId, orgSerialNo]
     * @return: java.lang.Boolean
     * @Author: cxc
     * @Date: 2018.04.13 09:56
     */
    @Override
    public Boolean exist(String userId, String orgSerialNo) {
        return userOrgMapper.findByUserIdAndOrgSerialNo(userId, orgSerialNo).size() > 0;
    }


    @Override
    public List<Organization> parentDeptList() throws Exception {
        return organizationMapper.parentDeptList();
    }

    @Override
    public List<Organization> list(Map<String, Object> map) {
        return organizationMapper.getSonDeptBySno(map);
    }

    /**
     *@Description 通过用户名、部门名模糊查询
     *@Param: [organization]
     *@return: com.kingyea.mobilepolice.system.Result
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    @Override
    public Result searchByName(Organization organization){

        Result result=new Result();
        List<Organization> organizationList=organizationMapper.searchByName(organization);
        List<User> userList=userMapper.searchByName(organization.getName());
        Map<String,Object> returnList=new HashMap<String,Object>();
        returnList.put("organizationList",organizationList);
        returnList.put("userList",userList);
        result.setData(returnList);
        return  result;
    }

    /**
     *@Description 获取个人信息（个人名片使用）
     *@Param: [userId]
     *@return: com.kingyea.mobilepolice.system.Result
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    @Override
    public Result searchPersionCard(String userId){

        Result result=new Result();
        User user=userMapper.getByUserId(userId);
        if(user!=null) {
            if (user.getJobCategory() != null) {
                Dictionary dictionary = dictionaryMapper.searchByValue(user.getJobCategory(),new String("jobCategory"));
                if(dictionary!=null) {
                    user.setJobCategory(dictionary.getName());
                }
            }
            if(user.getQuarters()!=null){
                Dictionary dictionary=dictionaryMapper.searchByValue(user.getQuarters(),new String("user_type"));
                if(dictionary!=null){
                    user.setQuarters(dictionary.getName());
                }
            }
            Organization org = organizationMapper.getBySerialNo(user.getOrgSerialNo());
            user.setOrgSerialNo(org.getName());
        }
        result.setData(user);
        return  result;
    }

    /**
     *@Description 获取部门信息和上级部门（部门名片使用）
     *@Param: [orgId]
     *@return: com.kingyea.mobilepolice.system.Result
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    @Override
    public Result searchCard(String orgId) {

        Result result=new Result();
        Organization org=organizationMapper.getBySerialNo(orgId);//当前部门
        Organization parentOrg=organizationMapper.getBySerialNo(org.getParentSerialNo());//父级部门
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("currDept",org);
        map.put("parentDept",parentOrg);
        result.setData(map);
        return  result;
    }

    /**
     *@Description 返回最高级别部门以及自己的信息
     *@Param: []
     *@return: com.kingyea.mobilepolice.system.Result
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    @Override
    public Result selectByMyDept() {

        Result result= new Result();
        try {
            User user=userMapper.getByUserId("1d62db83-ee9c-4726-8eb1-fda0dd328e46");
            List<OrganizationVo> list=new ArrayList<>();
            Organization org=organizationMapper.getparentDept();//获取最高级别部门
            OrganizationVo vo=new OrganizationVo();
            BeanUtils.copyProperties(org, vo);
            //Organization myorg=organizationMapper.getBySerialNo(SecurityUtils.getCurrentUser().getOrgSerialNo());//获取自己所在部门
            List<OrganizationVo> child=new ArrayList<>();
            if(user.getOrgSerialNo()!=null){
                Organization myorg=organizationMapper.getBySerialNo(user.getOrgSerialNo());//获取自己所在部门
                if(myorg!=null) {
                    OrganizationVo vo1 = new OrganizationVo();
                    BeanUtils.copyProperties(myorg, vo1);
                    child.add(vo1);
                }
            }
            if(user.getCrossSection()!=null&& !user.getCrossSection().equals(org.getOrgSerialNo())) {//跨职部门
                Organization myCrossSection = organizationMapper.getBySerialNo(user.getCrossSection());//获取跨职部门
                OrganizationVo vo2=new OrganizationVo();
                BeanUtils.copyProperties(myCrossSection, vo2);
                child.add(vo2);
            }
            vo.setOrganizationVos(child);
            result.setData(vo);
        } catch (Exception e) {
            LOGGER.error(e.getMessage());
            e.printStackTrace();
        }
        return result;
    }

    /**
     *@Description 获取自己的下级部门和人员
     *@Param: [orgId]
     *@return: com.kingyea.mobilepolice.system.Result
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    @Override
    public Result searchMyDept(String orgId) {

        List<User> userList=userMapper.getByOrgId(orgId);
        List<Organization> organizationList=organizationMapper.getMyDept(orgId);
        Result result=new Result();
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("userList",userList);
        map.put("organizationList",organizationList);
        map.put("myParent",searchMyParent(orgId));  //调用获取我的所有上级部门方法
        result.setData(map);
        return  result;
    }

    /**
     *@Description 获取自己的所有上级部门
     *@Param: [orgId]
     *@return: com.kingyea.mobilepolice.system.Result
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    public Result searchMyParent(String orgId) {

        Result result=new Result();
        Organization org = organizationMapper.getBySerialNo(orgId);

        OrganizationVo orgVo = new OrganizationVo();
        BeanUtils.copyProperties(org, orgVo);
        Organization o = seachParent(orgVo);

        result.setData(o);
        return  result;
    }

    /**
     *@Description 获取当前部门的上级部门
     *@Param: [currOrg]
     *@return: com.kingyea.mobilepolice.organization.bean.OrganizationVo
     *@Author: lgy
     *@Date: 2018/8/20 0020
     */
    public OrganizationVo seachParent(OrganizationVo currOrg){

        OrganizationVo orgVo = new OrganizationVo();
        BeanUtils.copyProperties(currOrg, orgVo);
        if(currOrg.getParentSerialNo().equals("-1")){
            return orgVo;
        }else{
            OrganizationVo parentOrgVo = new OrganizationVo();
            BeanUtils.copyProperties(organizationMapper.getBySerialNo(orgVo.getParentSerialNo()), parentOrgVo);
            parentOrgVo.setOrganizationVos(Lists.newArrayList(orgVo));
            return seachParent(parentOrgVo);
        }
    }


}
